xen/arm: acpi: Map MMIO on fault in stage-2 page table for the hardware domain
When booting using ACPI, not all MMIOs can be discovered by parsing the
static tables or the UEFI memory map. A lot of them will be described in
the DSDT. However, Xen does not have an AML parser which requires us to
find a different approach.
During the first discussions on supporting ACPI (see design doc [1]), it
was decided to rely on the hardware domain to make a request to the
hypervisor to map the MMIO region in stage-2 page table before accessing
it. This approach works fine if the OS has limited hooks to modify the
page tables.
In the case of Linux kernel, notifiers have been added to map
the MMIO regions when adding a new AMBA/platform device. Whilst this is
covering most of the MMIOs, some of them (e.g OpRegion, ECAM...) are not
related to a specific device or the driver is not using the
AMBA/platform API. So more hooks would need to be added in the code.
Various approaches have been discussed (see [2]), one of them was to
create stage-2 mappings seamlessly in Xen upon hardware memory faults.
This approach was first ruled out because it relies on the hardware
domain to probe the region before any use. So this would not work when
DMA'ing to another device's MMIO region when the device is protected by
an SMMU. It has been pointed out that this is a limited use case compare
to DMA'ing between MMIO and RAM.
This patch implements this approach. All MMIOs region will be mapped in
stage-2 using p2m_mmio_direct_c (i.e normal memory outer and inner
write-back cacheable). The stage-1 page table will be in control of the
memory attribute. This is fine because the hardware domain is a trusted
domain.
Note that MMIO will only be mapped on a data abort fault. It is assumed
that it will not be possible to execute code from MMIO
(p2m_mmio_direct_c will forbid that).
As mentioned above, this solution will cover most of the cases. If a
platform requires to do DMA'ing to another device's MMIO region without
any access performed by the OS. Then it will be expected to have
specific platform code in the hypervisor to map the MMIO at boot time or
the OS to use the existing hypercalls (i.e XENMEM_add_to_add_physmap{,_batch})
before any access.
[1] https://lists.xen.org/archives/html/xen-devel/2015-11/msg00488.html
[2] https://marc.info/?l=linux-arm-kernel&m=
148469169210500&w=2
Signed-off-by: Julien Grall <julien.grall@arm.com>
Tested-by: Shanker Donthineni <shankerd@codeaurora.org>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>